#!/user/bin/python
# coding=utf-8
from time import sleep
import re
import subprocess
import os
import sys
import serial
import test
import common
import signal
import fcntl
import psutil
from time import sleep
from multiprocessing import Process, Event
from multiprocessing import Queue as PQueue
from threading import Thread
from Queue import Queue, Empty
from select import select

execfile("../cfg/at/other.cfg")

thread = None
cancel_event = Event()
output = Queue()


def pre_exec():
    os.setpgid(0, 0)


def ppp_daemon(queue):
    ppp_pipe = subprocess.Popen(["./../cfg/ppp/air-ppp-on", "--usepeernds=1"], bufsize=1, preexec_fn=pre_exec,
                                shell=False, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    fd = ppp_pipe.stdout.fileno()
    flag = fcntl.fcntl(fd, fcntl.F_GETFD)
    fcntl.fcntl(fd, fcntl.F_SETFL, flag | os.O_NONBLOCK)
    while not cancel_event.is_set():
        buf = ''
        while True:
            try:
                char = os.read(fd, 1)
            except:
                break
            else:
                if not char:
                    break
                buf += char
        if buf != '':
            queue.put(buf)
    for p in psutil.Process(ppp_pipe.pid).children(recursive=True):
        try:
            p.send_signal(signal.SIGTERM)
            p.wait()
        except:
            pass
    os.kill(ppp_pipe.pid, signal.SIGINT)
    os.waitpid(ppp_pipe.pid, os.WNOHANG)


def _ppp_daemon_impl(queue):
    pipe = os.popen("./../cfg/ppp/air-ppp-on --usepeernds=1")
    while True:
        signal.alarm(4)
        line = pipe.readline()
        signal.alarm(0)
        if line:
            line = line.strip()
            queue.put(line)


def _ppp_daemon(queue):
    ps = Process(target=_ppp_daemon_impl, args=(queue,))
    ps.start()
    while not cancel_event.is_set():
        sleep(1)
    for p in psutil.Process(ps.pid).children(recursive=True):
        p.send_signal(signal.SIGTERM)
        p.wait()
    os.kill(ps.pid, signal.SIGTERM)
    os.waitpid(ps.pid, os.WNOHANG)


def output_print(queue):
    while True:
        try:
            item = output.get_nowait()
        except Empty:
            break
        else:
            lines = item.splitlines()
            for line in lines:
                print line


def start_ppp(result):
    # ppp拨号
    print '开始拨号'
    print '正在拨号，请稍等。。。。'
    result.add_test_time(1)
    times = 0
    global thread
    global output
    global cancel_event
    thread = Thread(target=ppp_daemon, args=(output,))
    thread.start()
    while True:
        connect = os.popen("./../cfg/ppp/air-ppp-status").read()
        if cmp(connect, "connected\n") == 0:
            print "拨号成功"
            result.add_suc_time(1)
            break
        else:
            sleep(1)
            times = times + 1
            if times == 10:
                result.add_fail_time(1)
                print '拨号失败'
                cancel_event.set()
                thread.join()
                output_print(output)
                os.system('./../cfg/ppp/air-ppp-off')
                # test.diag_exit()
                test.output_result()
                os._exit(2)


def close_ppp():
    # ppp断开
    for i in range(len(test.LocIfList)):
        os.system("ifconfig "+test.LocIfList[i]+" up")
        print "ifconfig "+test.LocIfList[i]+" up"

    cancel_event.set()
    thread.join()
    connect = os.popen("./../cfg/ppp/air-ppp-status").read()
    if cmp(connect, "connected\n") == 0:
        print '断开拨号'
        os.system("./../cfg/ppp/air-ppp-off")


def run(result_object):
    ser = ""
    for i in range(test_ppp_loop):
        ser = common.ser_is_ok(dev_port)

        if common.net_is_ok(ser):
            start_ppp(result_object)
            common.set_all_net()
            common.ping_test(result_object, "ping -c "+str(ppp_ping_loop) +
                             " www.baidu.com"+" -I"+" ppp0", ppp_ping_loop)
            common.ping_test(result_object, "ping -c "+str(ppp_ping_loop) +
                             " www.youku.com"+" -I"+" ppp0", ppp_ping_loop)
            close_ppp()
